<!--
 * @Description: 综合统计页面 - 支持按月份/季度统计客户新增数量与订单总金额（前端聚合+ECharts）
 * @Author: lujq
 * @Date: 2025-08-25
 * @LastEditors: lujq
 * @LastEditTime: 2025-08-25 17:25:00
-->
<template>
  <div class="statistics-page">
    <el-card class="filter-card" shadow="never">
      <el-form :inline="true" :model="filters">
        <el-form-item label="统计维度">
          <el-select v-model="filters.dimension" style="width: 160px" @change="refreshAll">
            <el-option label="按月份" value="month" />
            <el-option label="按季度" value="quarter" />
          </el-select>
        </el-form-item>
        <el-form-item label="时间范围">
          <el-date-picker
            v-model="filters.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            value-format="YYYY-MM-DD"
            @change="refreshAll"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="refreshAll">查询</el-button>
          <el-button :icon="Refresh" @click="resetFilters">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <el-row :gutter="16" class="mt-16">
      <el-col :span="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <span>客户新增数量（{{ filters.dimension === 'month' ? '月' : '季' }}度）</span>
            </div>
          </template>
          <div ref="customerChartRef" class="chart-container" />
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card shadow="never">
          <template #header>
            <div class="card-header">
              <span>订单总金额（{{ filters.dimension === 'month' ? '月' : '季' }}度）</span>
            </div>
          </template>
          <div ref="orderChartRef" class="chart-container" />
        </el-card>
      </el-col>
    </el-row>

    <el-card class="mt-16" shadow="never">
      <template #header>
        <div class="card-header">
          <span>明细预览</span>
        </div>
      </template>
      <el-table :data="previewTable" border size="small" height="360px">
        <el-table-column prop="period" label="周期" width="160" />
        <el-table-column prop="newCustomers" label="新增客户数" width="140" />
        <el-table-column prop="orderAmount" label="订单总金额" />
      </el-table>
    </el-card>
  </div>
</template>

<script setup lang="ts">
/**
 * @description 组件脚本：
 * 1. 拉取客户与订单数据（大页数获取全量）
 * 2. 基于选择的时间维度（月/季）进行前端聚合
 * 3. 使用 ECharts 渲染柱状图与折线图
 */
import { ref, reactive, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import { Search, Refresh } from '@element-plus/icons-vue'
import { getCustomerList } from '@/api/customer'
import { getOrderList } from '@/api/order'
import type { Customer, Order } from '@/types'

// 过滤条件
const filters = reactive({
  dimension: 'month' as 'month' | 'quarter',
  dateRange: [dayjs().startOf('year').format('YYYY-MM-DD'), dayjs().endOf('year').format('YYYY-MM-DD')] as [string, string],
})

// 图表引用
const customerChartRef = ref<HTMLDivElement | null>(null)
const orderChartRef = ref<HTMLDivElement | null>(null)
let customerChart: echarts.ECharts | null = null
let orderChart: echarts.ECharts | null = null

// 明细预览表数据
const previewTable = ref<Array<{ period: string; newCustomers: number; orderAmount: number }>>([])

// 拉取全量数据（通过较大 pageSize）
async function fetchAllCustomers(): Promise<Customer[]> {
  const res = await getCustomerList({ page: 1, pageSize: 5000 })
  return res.data.list || []
}

async function fetchAllOrders(): Promise<Order[]> {
  const res = await getOrderList({ page: 1, pageSize: 5000 })
  return res.data.list || []
}

// 工具：根据维度生成周期键
function getPeriodKey(date: string, dim: 'month' | 'quarter') {
  const d = dayjs(date)
  if (!d.isValid()) return ''
  return dim === 'month' ? d.format('YYYY-MM') : `${d.year()}-Q${Math.floor(d.month() / 3) + 1}`
}

// 聚合逻辑
function aggregate(customers: Customer[], orders: Order[]) {
  const [start, end] = filters.dateRange
  const dim = filters.dimension

  const custMap = new Map<string, number>()
  const orderMap = new Map<string, number>()

  customers.forEach((c) => {
    if (!c.createTime) return
    if (dayjs(c.createTime).isBefore(start) || dayjs(c.createTime).isAfter(end)) return
    const key = getPeriodKey(c.createTime, dim)
    custMap.set(key, (custMap.get(key) || 0) + 1)
  })

  orders.forEach((o) => {
    if (!o.createTime) return
    if (dayjs(o.createTime).isBefore(start) || dayjs(o.createTime).isAfter(end)) return
    const key = getPeriodKey(o.createTime, dim)
    orderMap.set(key, (orderMap.get(key) || 0) + (o.finalAmount ?? o.totalAmount ?? 0))
  })

  // 生成完整周期序列
  const periods: string[] = []
  const startD = dayjs(start)
  const endD = dayjs(end)
  if (dim === 'month') {
    let cur = startD.startOf('month')
    while (cur.isBefore(endD) || cur.isSame(endD, 'month')) {
      periods.push(cur.format('YYYY-MM'))
      cur = cur.add(1, 'month')
    }
  } else {
    // quarter：避免使用 dayjs 的 'quarter' 单位以规避 TS 类型限制，按每3个月为一季度推进
    const startQuarterMonth = Math.floor(startD.month() / 3) * 3
    let cur = startD.month(startQuarterMonth).startOf('month')
    const endQuarterIndex = endD.year() * 4 + Math.floor(endD.month() / 3)
    while (cur.year() * 4 + Math.floor(cur.month() / 3) <= endQuarterIndex) {
      const q = `${cur.year()}-Q${Math.floor(cur.month() / 3) + 1}`
      if (!periods.includes(q)) periods.push(q)
      cur = cur.add(3, 'month')
    }
  }

  const newCustomers = periods.map((p) => custMap.get(p) || 0)
  const orderAmounts = periods.map((p) => Number((orderMap.get(p) || 0).toFixed(2)))

  previewTable.value = periods.map((p, i) => ({
    period: p,
    newCustomers: newCustomers[i],
    orderAmount: orderAmounts[i],
  }))

  return { periods, newCustomers, orderAmounts }
}

// 渲染图表
function renderCharts(periods: string[], newCustomers: number[], orderAmounts: number[]) {
  if (!customerChart && customerChartRef.value) {
    customerChart = echarts.init(customerChartRef.value)
  }
  if (!orderChart && orderChartRef.value) {
    orderChart = echarts.init(orderChartRef.value)
  }

  customerChart?.setOption({
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: periods },
    yAxis: { type: 'value', name: '新增客户数' },
    series: [
      {
        name: '新增客户',
        type: 'bar',
        data: newCustomers,
        itemStyle: { color: '#409EFF' },
      },
    ],
  })

  orderChart?.setOption({
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: periods },
    yAxis: { type: 'value', name: '订单金额(¥)' },
    series: [
      {
        name: '订单总金额',
        type: 'line',
        smooth: true,
        areaStyle: {},
        data: orderAmounts,
        itemStyle: { color: '#67C23A' },
      },
    ],
  })
}

async function refreshAll() {
  try {
    const [customers, orders] = await Promise.all([fetchAllCustomers(), fetchAllOrders()])
    const { periods, newCustomers, orderAmounts } = aggregate(customers, orders)
    renderCharts(periods, newCustomers, orderAmounts)
  } catch (e) {
    ElMessage.error('加载数据失败，请稍后重试')
  }
}

function resetFilters() {
  filters.dimension = 'month'
  filters.dateRange = [dayjs().startOf('year').format('YYYY-MM-DD'), dayjs().endOf('year').format('YYYY-MM-DD')]
  refreshAll()
}

function handleResize() {
  customerChart?.resize()
  orderChart?.resize()
}

onMounted(() => {
  refreshAll()
  window.addEventListener('resize', handleResize)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped>
.statistics-page {
  padding: 8px;
}
.filter-card {
  margin-bottom: 12px;
}
.mt-16 {
  margin-top: 16px;
}
.chart-container {
  width: 100%;
  height: 360px;
}
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 500;
}
</style>